#include "keyboard.h"
#include "defuns.h"
//para debug
#include "video.h"



static unsigned char keyMap[NUM_SUPPORTED_KEYBOARDS][NUM_MAPPINGS][NUM_KEYS]={
{
	{	ASCII_ERROR,
		ASCCI_ESC 	, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-' , '=', '\b',
		'\t'		, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[' , ']', '\n',
		ASCII_CTRL	, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', ASCII_ENIE, ASCII_LSHIFT,
		'\\'   		, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',  ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND},
	{	ASCII_ERROR,
		ASCCI_ESC 	, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-'	, '=' , '\b',
		'\t'		, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '['	, ']' , '\n',
		ASCII_CTRL	, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', '\'', ASCII_ENIE, ASCII_LSHIFT,
		'\\' 		, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/', ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND},
	{	ASCII_ERROR,
		ASCCI_ESC	, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_'	, '+', '\b',
		'\t'		, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{'	, '}', '\n',
		ASCII_CTRL	, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', ASCII_ENIE, ASCII_LSHIFT,
		'|' 		, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '\?', ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND},
	{	ASCII_ERROR,
		ASCCI_ESC	, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, 'ẃ', 'é', 'ŕ', ND, 'ý', 'ú', 'í', 'ó', ND, '´', ND, ND,
		ASCII_CTRL	, 'á', 'ś', ND, ND, ND, ND, ND, ND, 'ĺ', ':', '\"', ASCII_ENIE, ASCII_LSHIFT,
		'|' 		, 'ź', ND, 'ć', ND, ND, 'ń', ND, ND, ND, ND, ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND}
},	
{
	{	ASCII_ERROR,
		ASCCI_ESC 	, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-' , '=', '\b',
		'\t'		, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '`', '+', '\n',
		ASCII_CTRL	, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', '�', '[' , ']', ASCII_LSHIFT,
		'\\'   		, 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '-',  ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND},
	{	ASCII_ERROR,
		ASCCI_ESC 	, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-'	, '=', '\b',
		'\t'		, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '`'	, '+' , '\n',
		ASCII_CTRL	, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '�', '[' , ']' , ASCII_LSHIFT,
		'\\' 		, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '-', ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND},
	{	ASCII_ERROR,
		ASCCI_ESC	, '!', '\"', '#', '$', '%', '&', '/', '(', ')', '=', '\?', '�', '\b',
		'\t'		, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '�', '*'	, '\n',
		ASCII_CTRL	, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', '�', '{' , '}'	, ASCII_LSHIFT,
		'|' 		, 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ';', ':', '_', ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND},
	{	ASCII_ERROR,
		ASCCI_ESC	, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, 'ẃ', 'é', 'ŕ', ND, 'ý', 'ú', 'í', 'ó', ND, '´', ND, ND,
		ASCII_CTRL	, 'á', 'ś', ND, ND, ND, ND, ND, ND, 'ĺ', ':', '\"', ASCII_ENIE, ASCII_LSHIFT,
		'|' 		, 'ź', ND, 'ć', ND, ND, 'ń', ND, ND, ND, ND, ASCII_RSHIFT, ASCII_PRTSC,
		ASCII_RALT	, ' ', ND, ND, ND/*pos 60*/,	
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND, ND, ND, ND, ND, ND, ND,
		ND, ND, ND, ND,ND, ND}
}
};


static char specialKeys = 0x00;
/*Tipo de teclado utilizado*/
static int currentKeyBoard = US_KEYBOARD;





/*Elimina el break de la tecla(La toma como si fue apretada)*/
#define FILTER_BREAK(code)	((code) & (~0x0080))

void
setKeyBoard(int kb)
{
	currentKeyBoard = kb;
	return;
}


static char _keyBuffer[KEY_BUFFER_SIZE];
static int _keyBufferPos;

void
freeKeyBuffer(){
	_keyBufferPos = 0;
	_keyBuffer[0] = '\0';
	return;
}

void
addToKeyBuffer(char ascii)
{
	if(_keyBufferPos > KEY_BUFFER_SIZE-2)
	{
		freeKeyBuffer();
		return;
	}
	if(ascii == '\n')
		freeKeyBuffer();
	else
	{
		if(ascii == '\b')
		{
			if(_keyBufferPos>0)
			{
				_keyBuffer[_keyBufferPos-1]= '\0';
				_keyBufferPos--;
				backSpaceCursor();
			}
		}
		else
		{
			_keyBuffer[_keyBufferPos]= ascii;
			_keyBuffer[_keyBufferPos+1]= '\0';
			_keyBufferPos++;
		}
	}
	
	return;
}

char
getKeyBufferHead()
{
	return _keyBuffer[_keyBufferPos-1];
}

char*
getKeyBuffer()
{
	return _keyBuffer;
}

int 
processSpecial(int code)
{
	/*Guardo si la tecla fue liberada*/
	int breakCode = (code & BREAKCODE);
	char sCode = 0x00;
	
	if(breakCode)
		breakCode = 0xff;/*La tecla se solto*/
	else
		breakCode = 0x00;/*La tecla se presiono*/
	
	code = FILTER_BREAK(code);

	if(code==ESC)
		sCode = S_ESC;
	else if(code==ENTER)
		sCode = S_ENTER;
	else if(code==LSHIFT)
		sCode = S_LSHIFT;
	else if(code==RSHIFT)
		sCode = S_RSHIFT;
	else if(code==ACCENT)
		sCode = S_ACCENT;
	else if(code==RCTRL || code==LCTRL)
		sCode = S_CTRL;
	else if(code==CAPSLOCK)
	{
		if(!breakCode)
		{
			if(specialKeys & S_CAPSLOCK)
			{
				//putCharCursor('c');
				specialKeys = specialKeys & !S_CAPSLOCK;
			}
			else
				specialKeys = specialKeys | S_CAPSLOCK;
			return TRUE;
		}
		return TRUE;
	}
	else
		return FALSE;
	
	/*Mapeo la tecla al vector de teclas especiales*/
	if(breakCode)
		specialKeys = specialKeys & !sCode ;
	else
		specialKeys = specialKeys | sCode;
	
	return TRUE;
}

int
isKeyPressed(int code){
	if(!(code & 0x0080))
		return FALSE;
	
	return TRUE;
}

char
getEspecials()
{
	return specialKeys;
}


char
toAscii(int code)
{
	code = FILTER_BREAK(code);
	
	/*Si esta apretada la tecla shift mapeo segun el teclado en shift*/
	if((specialKeys & S_RSHIFT) || (specialKeys & S_LSHIFT))
		return keyMap[currentKeyBoard][SHIFT_PRESSED][code];
	/*Si esta apretada la tecla caps-lock mapeo segun el teclado en caps-lock*/
	else if(specialKeys & S_CAPSLOCK)
	{
		return keyMap[currentKeyBoard][CAPS_LOCK_PRESSED][code];

	}else if(specialKeys & S_ACCENT)
	{
		return keyMap[currentKeyBoard][ACCENT_PRESSED][code];
	}else
		return keyMap[currentKeyBoard][NORMAL][code];
}



